#include "precomp.h"
#include "EntityDoodadd.h"
#include "../Entity.h"
#include "../../Map/Grid.h"

namespace Tmpl {

#define DOODADD_JOBS 8

static DataValuePool<EntityDoodadd> gDoodadds;

// EntitUnityDoodaddystem setup functions
void EntityDoodaddSystem::Init()
{
	gDoodadds.Init();
}
void EntityDoodaddSystem::Clear()
{
	gDoodadds.Clear();
}
int EntityDoodaddSystem::NewDoodadd(Entity* owner, Vec2f pos, const UnitData& data)
{
	int id = gDoodadds.NewValue();

	EntityDoodadd* value = gDoodadds.GetValue(id);
	value->mOwner = owner;
	value->mPos = pos;
	value->mHP = value->mHPMax = data.doodadd.hp;
	value->mSize = data.doodadd.size;

	// add entity to grid
	Grid::AddEntity(value->mOwner, Grid::GetCellIdFromPos(value->mPos));

	return id;
}
void EntityDoodaddSystem::RemoveDoodadd(int id)
{
	// remove from grid
	EntityDoodadd* value = gDoodadds.GetValue(id);
	Grid::RemoveEntity(value->mOwner, Grid::GetCellIdFromPos(value->mPos));

	gDoodadds.RemoveValue(id);
}
EntityDoodadd* EntityDoodaddSystem::GetDoodadd(int id)
{
	return gDoodadds.GetValue(id);
}
// EntityDoodadd
void EntityDoodadd::Kill()
{
	mHP = 0.0f;
	mHPMax = 0.0f;
	ConditionRemoveFlag(DOODADD_CONDITION_ALIVE);
	ConditionAddFlag(DOODADD_CONDITION_DEAD);
}
void EntityDoodadd::AddHP(float hp, int entitySource)
{
	if (mHPMax <= 0.0f) return;
	mHP += hp;

	// Kill unit if hp drops below 0
	if (mHP < 0.0f && ConditionHasFlag(DOODADD_CONDITION_ALIVE))
	{
		ConditionRemoveFlag(DOODADD_CONDITION_ALIVE);
		ConditionAddFlag(DOODADD_CONDITION_DEAD);

		// perhaps send a message to the killer?
	}

	// Clamp it
	mHP = Clamp(0.0f, mHPMax, mHP);
}
// Updating
void EntityDoodaddSystem::UpdateDoodaddChunk(int chunk)
{
	int count = gDoodadds.GetValueCount();
	int step = count / DOODADD_JOBS;
	int from = step * chunk;
	int to = ((chunk==DOODADD_JOBS-1) ? count : step * (chunk+1));
	for (int i=from; i<to; ++i)
	{
		EntityDoodadd* v = gDoodadds.GetUnmappedValue(i);
		Entity* ent = v->mOwner;

		if (v->mHP <= 0.0f && v->mHPMax > 0.0f)
		{
			v->Kill();
			ent->Kill();
		}
	}
}
JobHandle EntityDoodaddSystem::Update(JobHandle dependency)
{
	JobHandle DoodaddUpdate = JobManager::NewJob();
	for (int i=0; i<DOODADD_JOBS; ++i)
	{
		JobHandle job = JobManager::NewJob(&EntityDoodaddSystem::UpdateDoodaddChunk,i);
		JobManager::AddJobDependency(job, dependency);
		JobManager::AddExecuteJob(job);
		JobManager::AddJobDependency(DoodaddUpdate, job);
	}
	JobManager::AddExecuteJob(DoodaddUpdate);
	return DoodaddUpdate;
}
}